'''
版权：Copyright (c) 2019 China

创建日期：Monday December 23rd 2019
创建者：ymq(ymq) - <<email>>

修改日期: Monday, 23rd December 2019 2:28:23 pm
修改者: ymq(ymq) - <<email>>

说明
 1、补贴账户充值
'''
from datetime import datetime
from ...service.constant import AccountType, AccountStatus, PayType, PayStatue, plat_id
from ...service.mongo_bill_service import MongoBillFilter
from server.pao_python.pao.service.data.mongo_db import MongoService, MongoFilter, C, N, F, as_date
from ...service.buss_pub.bill_manage import BillManageService, TypeId, OperationType, Status


class SubsidyAccountRechargService(MongoService):
    def __init__(self, db_addr, db_port, db_name, db_user, db_pwd, inital_password, session):
        self.db_addr = db_addr
        self.db_port = db_port
        self.db_name = db_name
        self.db_user = db_user
        self.db_pwd = db_pwd
        self.inital_password = inital_password
        self.session = session
        self.bill_manage_server = BillManageService(
            db_addr, db_port, db_name, db_user, db_pwd, inital_password, session)

    def __get_account_balance(self, account_id):
        '''获取账户余额'''
        _filter = MongoBillFilter()
        _filter.match_bill(C('account_id') == account_id)\
               .sort({'date': -1})\
               .limit(1)
        res = self.query(_filter, 'PT_Financial_Account_Record')
        if len(res) == 0:
            return 0
        else:
            return res[0]['balance']

    def get_subsidy_list(self, org_list, condition, page, count):
        '''获取补贴人员列表(只显示兜底老人)'''
        keys = ['personnel_classification_id', 'organization_id', 'balance_low', 'balance_upper',
                'name', 'card_id']  # personnel_classification_id为列表，organization_id为单个，若选全部则不传该字段
        if condition.get('balance_low'):
            condition['balance_low'] = int(condition['balance_low'])
        elif condition.get('balance_upper'):
            condition['balance_upper'] = int(condition['balance_upper'])
        values = self.get_value(condition, keys)
        _filter = MongoBillFilter()
        _filter.match_bill((C('organization_id').inner(org_list))
                           & (C('personnel_info.personnel_classification') != '') & (C('personnel_info.personnel_classification') != None))\
               .lookup_bill('PT_Personnel_Classification', 'personnel_info.personnel_classification', 'id', 'classification_info')\
               .match_bill((C('classification_info.type') == '政府补贴'))\
               .add_fields({
                   'card_id': '$personnel_info.id_card',
                   'sex': '$personnel_info.sex',
                   'type': '$classification_info.name'
               })\
            .match_bill((C('personnel_info.personnel_classification') == values['personnel_classification_id']))\
            .inner_join_bill('PT_Personnel_Classification', 'personnel_info.personnel_classification', 'id', 'classification_info')\
            .inner_join_bill('PT_Financial_Account', 'id', 'user_id', 'account_info')\
            .lookup_bill('PT_Bed', 'id', 'residents_id', 'org_info')\
            .lookup_bill('PT_Financial_Account_Record', 'account_info.id', 'account_id', 'record_all_info')\
            .add_fields({'record_info': self.ao.array_filter('$record_all_info', 'tep', ((F('$tep.amount') < 0) & (F('$tep.is_clean') != True)).f)})\
            .add_fields({'amount': self.ao.absolute(self.ao.summation('$record_info.amount'))})\
            .match((C('account_info.name') == AccountType.account_subsidy)
                   & (C('account_info.balance') >= values['balance_low'])
                   & (C('account_info.balance') <= values['balance_upper'])
                   & (C('name').like(values['name']))
                   & (C('personnel_info.id_card') == values['card_id']))\
            .lookup_bill('PT_User', 'org_info.organization_id', 'id', 'org_name')
        if condition.get('organization_id'):
            _filter.unwind('org_info')\
                   .match(C('org_info.organization_id') == values['organization_id'])
        _filter.project({'_id': 0, 'org_name': '$org_name.name',
                         'type': '$classification_info.name', 'balance': '$account_info.balance', 'amount': 1, 'user_id': '$id', 'name': 1, 'card_id': 1, 'sex': 1})
        res = self.page_query(
            _filter, 'PT_User', page, count)
        return res

    def recharg_subsidy_account(self, org_list, condition):
        '''充值补贴账户
        Args：condition中：amount和remark必须有，personnel_classification_id(数组)和id只允许传其中一个
        '''
        if condition.get('personnel_classification_id'):
            _filter = MongoBillFilter()
            _filter.match_bill((C('organization_id').inner(org_list)) & (C('classification_id').inner(condition['personnel_classification_id'])))\
                   .inner_join_bill('PT_Financial_Account', 'user_id', 'user_id', 'account_info')\
                   .match(C('account_info.name') == AccountType.account_subsidy)\
                   .project({'_id': 0, 'account_id': '$account_info.id'})
            account_ids = self.query(_filter, 'PT_Government_Subsidy_User')
        elif condition.get('id'):
            _filter = MongoBillFilter()
            _filter.match_bill((C('user_id') == condition['id']) & (C('name') == AccountType.account_subsidy))\
                   .project({'_id': 0, 'account_id': '$id'})
            account_ids = self.query(_filter, 'PT_Financial_Account')
        else:
            return False
        amount = int(condition['amount'])
        res_clean = False
        res_recharge = False
        if len(account_ids) > 0:
            # step1:清零
            clean_account_list = []
            clean_record_list = []

            _filter=MongoBillFilter()
            _filter.match_bill(C('account_id').inner([i['account_id'] for i in account_ids]))\
                   .group({'account_id':'$account_id'},[{'new_date':self.ao.maximum('$date')}])\
                   .lookup_bill('PT_Financial_Account_Record','account_id','account_id','new_data')\
                   .add_fields({'newest':self.ao.array_elemat(self.ao.array_filter('$new_data','tep',(F('$tep.date')=='$new_date').f),0)})\
                   .project({'balance':'$newest.balance','account_id':1})
            balance_list = self.query(_filter, 'PT_Financial_Account_Record')
            if len(balance_list) < len(account_ids) :
                for j in account_ids :
                    if j['account_id'] not in [i['account_id'] for i in balance_list] :
                        balance_list.append({'account_id':j['account_id'],'balance':0})   
            for i in balance_list :
                if i['balance']>0 :
                    clean_account_list.append(
                        {'balance': 0, 'id': i['account_id']})
                    clean_record_list.append({'account_id': i['account_id'], 'amount': i['balance'] * (
                        -1), 'balance': 0, 'abstract': '补贴账户清零', 'is_clean': True, 'date': datetime.now(), 'remarks': condition['remark']})
            if len(clean_account_list) > 0:
                self.bill_manage_server.add_bill(
                    OperationType.update.value, TypeId.financial.value, clean_account_list, 'PT_Financial_Account')
                self.bill_manage_server.add_bill(
                    OperationType.add.value, TypeId.financial.value, clean_record_list, 'PT_Financial_Account_Record')
                res_clean = True
            # step2:充值
            if amount > 0:
                recharge_account_list = []
                recharge_record_list = []
                for i in account_ids:
                    recharge_account_list.append(
                        {'id': i['account_id'], 'balance': amount})
                    recharge_record_list.append({'balance': amount, 'amount': amount, 'abstract': '补贴金额发放', 'date': datetime.now(
                    ), 'remarks': condition['remark'], 'account_id': i['account_id']})
                if len(recharge_account_list) > 0:
                    self.bill_manage_server.add_bill(
                        OperationType.update.value, TypeId.financial.value, recharge_account_list, 'PT_Financial_Account')
                    self.bill_manage_server.add_bill(
                        OperationType.add.value, TypeId.financial.value, recharge_record_list, 'PT_Financial_Account_Record')
                    res_recharge = True
        if amount == 0:
            return res_clean
        else:
            return res_recharge

    def get_subsidy_account_detail(self, condition, page, count):
        '''获取长者补贴账户明细'''
        keys = ['id', 'start_date', 'end_date']  # id为必传参数
        if condition.get('id'):
            if condition.get('date_range'):
                condition['start_date'] = condition['date_range'][0]
                condition['end_date'] = condition['date_range'][1]
            values = self.get_value(condition, keys)
            _filter = MongoBillFilter()
            _filter.match_bill((C('user_id') == condition['id']) & (C('name') == AccountType.account_subsidy))\
                   .inner_join_bill('PT_Financial_Account_Record', 'id', 'account_id', 'record_info')\
                   .match((C('date') > as_date(values['start_date'])) & (C('date') < as_date(values['end_date'])))\
                   .inner_join_bill('PT_User', 'user_id', 'id', 'user_info')\
                   .lookup_bill('PT_User', 'bill_operator', 'id', 'operator_info')\
                   .sort({'date': -1})\
                   .project({'_id': 0, 'record_info._id': 0, 'user_info._id': 0, 'operator_info._id': 0})
            res = self.page_query(_filter, 'PT_Financial_Account', page, count)
        else:
            res = False
        return res

    def get_charitable_subsidy_list(self, org_list, condition, page, count):
        '''获取慈善账户列表'''
        keys = ['personnel_classification_id', 'organization_id', 'balance_low', 'balance_upper',
                'name', 'card_id']  # personnel_classification_id为列表，organization_id为单个，若选全部则不传该字段
        if condition.get('balance_low'):
            condition['balance_low'] = int(condition['balance_low'])
        elif condition.get('balance_upper'):
            condition['balance_upper'] = int(condition['balance_upper'])
        values = self.get_value(condition, keys)
        _filter = MongoBillFilter()
        _filter.match_bill((C('organization_id').inner(org_list)) & (C('personnel_info.personnel_category') == '长者'))\
               .add_fields({
                   'card_id': '$personnel_info.id_card',
                   'sex': '$personnel_info.sex',
               })\
            .lookup_bill('PT_Financial_Account', 'id', 'user_id', 'account_info')\
            .lookup_bill('PT_Financial_Account_Record', 'account_info.id', 'account_id', 'record_all_info')\
            .add_fields({'record_info': self.ao.array_filter('$record_all_info', 'tep', (F('$tep.amount') < 0).f)})\
            .add_fields({'amount': self.ao.absolute(self.ao.summation('$record_info.amount'))})\
            .match((C('account_info.name') == AccountType.account_charitable)
                   & (C('account_info.balance') >= values['balance_low'])
                   & (C('account_info.balance') <= values['balance_upper'])
                   & (C('name').like(values['name']))
                   & (C('personnel_info.id_card') == values['card_id']))
        _filter.project({'_id': 0,
                         'balance': '$account_info.balance', 'amount': 1, 'user_id': '$id', 'name': 1, 'card_id': 1, 'sex': 1})
        res = self.page_query(
            _filter, 'PT_User', page, count)
        return res

    def recharg_charitable_account(self, org_list, condition):
        '''充值慈善账户
        Args：condition中：amount和remark必须有，personnel_classification_id(数组)和id只允许传其中一个
        '''
        if condition.get('id'):
            _filter = MongoBillFilter()
            _filter.match_bill((C('user_id') == condition['id']) & (C('name') == AccountType.account_charitable))\
                   .project({'_id': 0, 'account_id': '$id'})
            account_ids = self.query(_filter, 'PT_Financial_Account')
        else:
            return False
        amount = int(condition['amount'])
        if len(account_ids) > 0:
            # step1:清零
            clean_account_list = []
            clean_record_list = []
            for i in account_ids:
                balance = self.__get_account_balance(i['account_id'])
                if balance > 0:
                    clean_account_list.append(
                        {'balance': 0, 'id': i['account_id']})
                    clean_record_list.append({'account_id': i['account_id'], 'amount': balance * (
                        -1), 'balance': 0, 'abstract': '慈善账户清零', 'date': datetime.now(), 'remarks': condition['remark']})
            if len(clean_account_list) > 0:
                self.bill_manage_server.add_bill(
                    OperationType.update.value, TypeId.financial.value, clean_account_list, 'PT_Financial_Account')
                self.bill_manage_server.add_bill(
                    OperationType.add.value, TypeId.financial.value, clean_record_list, 'PT_Financial_Account_Record')
                res_clean = True
            # step2:充值
            if amount > 0:
                recharge_account_list = []
                recharge_record_list = []
                for i in account_ids:
                    recharge_account_list.append(
                        {'id': i['account_id'], 'balance': amount})
                    recharge_record_list.append({'balance': amount, 'amount': amount, 'abstract': '慈善金额充值', 'date': datetime.now(
                    ), 'remarks': condition['remark'], 'account_id': i['account_id']})
                if len(recharge_account_list) > 0:
                    self.bill_manage_server.add_bill(
                        OperationType.update.value, TypeId.financial.value, recharge_account_list, 'PT_Financial_Account')
                    self.bill_manage_server.add_bill(
                        OperationType.add.value, TypeId.financial.value, recharge_record_list, 'PT_Financial_Account_Record')
                    res_recharge = True
        if amount == 0:
            return res_clean
        else:
            return res_recharge

    def get_charitable_account_detail(self, condition, page, count):
        '''获取长者慈善账户明细'''
        keys = ['id', 'start_date', 'end_date']  # id为必传参数
        if condition.get('id'):
            if condition.get('date_range'):
                condition['start_date'] = condition['date_range'][0]
                condition['end_date'] = condition['date_range'][1]
            values = self.get_value(condition, keys)
            _filter = MongoBillFilter()
            _filter.match_bill((C('user_id') == condition['id']) & (C('name') == AccountType.account_charitable))\
                   .inner_join_bill('PT_Financial_Account_Record', 'id', 'account_id', 'record_info')\
                   .match((C('date') > as_date(values['start_date'])) & (C('date') < as_date(values['end_date'])))\
                   .inner_join_bill('PT_User', 'user_id', 'id', 'user_info')\
                   .lookup_bill('PT_User', 'bill_operator', 'id', 'operator_info')\
                   .sort({'date': -1})\
                   .project({'_id': 0, 'record_info._id': 0, 'user_info._id': 0, 'operator_info._id': 0})
            res = self.page_query(_filter, 'PT_Financial_Account', page, count)
        else:
            res = False
        return res

    def get_account_balance(self, org_list, condition, page, count):
        '''获取长者账户余额'''
        res = 'False'
        keys = ['user_id', 'account_name']  # user_id为必传参数
        values = self.get_value(condition, keys)
        _filter = MongoBillFilter()
        _filter.match_bill((C('user_id') == values['user_id']) & (C('name') == values['account_name']))\
            .sort({'date': -1})\
            .project({'_id': 0})
        res = self.page_query(_filter, 'PT_Financial_Account', page, count)
        return res
